package org.esprit.ocm.server.metier.ec2.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.esprit.ocm.client.rpc.ec2.SecurityGroupService;
import org.esprit.ocm.dto.ec2.impl.GroupDescriptionMappingDto;
import org.esprit.ocm.dto.ec2.impl.IpPermissionMappingDto;
import org.esprit.ocm.dto.impl.AwsCredentialsDto;
import org.esprit.ocm.dto.impl.ServerDto;

import com.xerox.amazonws.ec2.GroupDescription;
import com.xerox.amazonws.ec2.GroupDescription.IpPermission;
import com.xerox.amazonws.ec2.Jec2;

public class SecurityGroupServiceImpl extends BaseServiceImpl implements SecurityGroupService {

	/**
	 * Create a security group that can be assigned to an instance.
	 * 
	 * @param name
	 * @param description
	 * @return true if successfull, false else (e.g. if group with same name
	 *         already exists).
	 */
	public boolean createSecurityGroup(String name, String description, ServerDto server, AwsCredentialsDto credentials) {

		// initialize the interface
		Jec2 ec2 = this.initConnection(server, credentials);
		try {

			ec2.createSecurityGroup(name, description);

			return true;

		} catch (Exception ex) {
			Logger logger = Logger.getLogger(this.getClass().getName());
			logger.log(Level.SEVERE, "Creating security group failed: " + ex.getMessage());

			return false;
		}
	}

	/**
	 * Delete a security group.
	 * 
	 * @param name
	 *            Name of the group to delete. *
	 * @return true if successfull, false else (e.g. if group is assigned to a
	 *         running instance).
	 */
	public boolean deleteSecurityGroup(String name, ServerDto server, AwsCredentialsDto credentials) {

		// initialize the interface
		 Jec2 ec2 = this.initConnection(server, credentials);
		try {

			ec2.deleteSecurityGroup(name);

			return true;

		} catch (Exception ex) {
			Logger logger = Logger.getLogger(this.getClass().getName());
			logger.log(Level.SEVERE, "Deleting security group failed: " + ex.getMessage());

			return false;

		}
	}

	/**
	 * List all available Security groups.
	 * 
	 * @return
	 */
	public List<GroupDescriptionMappingDto> listSecurityGroups(ServerDto server, AwsCredentialsDto credentials) {

		// initialize the interface
		 Jec2 ec2 = this.initConnection(server, credentials);
		 

		 List<GroupDescriptionMappingDto> gmList = new ArrayList<GroupDescriptionMappingDto>();
		 List<GroupDescription> gList = new ArrayList<GroupDescription>();
		 List<IpPermissionMappingDto> ipList = new ArrayList<IpPermissionMappingDto>();

		try {
			
			gList = ec2.describeSecurityGroups(new ArrayList<String>());
			
			for (GroupDescription from : gList) {
				
				GroupDescriptionMappingDto to = new GroupDescriptionMappingDto();
				
				to.setName(from.getName());
				to.setDesc(from.getDescription());
				to.setOwner(from.getOwner());
				
				for (IpPermission fromIp : from.getPermissions()) {
					
					IpPermissionMappingDto toIp = new IpPermissionMappingDto();
					toIp.setProtocol(fromIp.getProtocol());
					toIp.setFromPort(fromIp.getFromPort());
					toIp.setToPort(fromIp.getToPort());
					toIp.setCidrIps(fromIp.getIpRanges());
					toIp.setUid_group_pairs(fromIp.getUidGroupPairs());
					ipList.add(toIp);
				}
				
				to.setPerms(ipList);
				gmList.add(to);
			}
			
			return gmList;
//			return ec2.describeSecurityGroups(new ArrayList<String>()).toArray(new GroupDescription[0]);

		} catch (Exception ex) {
			Logger logger = Logger.getLogger(this.getClass().getName());
			logger.log(Level.SEVERE, "Listing security groups failed: " + ex.getMessage());

			return null;

		}
	}

	/**
	 * Gets the properties of a specific security group.
	 * 
	 * @param name
	 *            The name of the group.
	 * @return GroupDescription or null in case of error or if group does not
	 *         exist.
	 */
	public GroupDescriptionMappingDto describeSecurityGroup(String name, ServerDto server, AwsCredentialsDto credentials) {

		// initialize the interface
		 Jec2 ec2 = this.initConnection(server, credentials);
		 List<IpPermissionMappingDto> ipList = new ArrayList<IpPermissionMappingDto>();

		try {
			GroupDescription from = ec2.describeSecurityGroups(new String[] { name }).get(0);
			GroupDescriptionMappingDto to = new GroupDescriptionMappingDto();
			
			to.setName(from.getName());
			to.setDesc(from.getDescription());
			to.setOwner(from.getOwner());
			
			for (IpPermission fromIp : from.getPermissions()) {
				
				IpPermissionMappingDto toIp = new IpPermissionMappingDto();
				toIp.setProtocol(fromIp.getProtocol());
				toIp.setFromPort(fromIp.getFromPort());
				toIp.setToPort(fromIp.getToPort());
				toIp.setCidrIps(fromIp.getIpRanges());
				toIp.setUid_group_pairs(fromIp.getUidGroupPairs());
				ipList.add(toIp);
			}
			
			to.setPerms(ipList);
			
			return to;

//			return ec2.describeSecurityGroups(new String[] { name }).get(0);

		} catch (Exception ex) {
			Logger logger = Logger.getLogger(this.getClass().getName());
			logger.log(Level.SEVERE, "Describing security group failed: " + ex.getMessage());

			return null;
		}

	}
}
